﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pink.Scheduler.RemoteInterfaces;
using System.Threading;
using Pink.Scheduler.DataAccess;

namespace Pink.Scheduler.RemoteInterfaces
{
	/// <summary>
	/// Очередь задач
	/// </summary>
	class TaskQueue
	{
		private Queue<TaskExecution> queue;
		private ManualResetEvent tasksAvailable;
		/// <summary>
		/// Конструктор
		/// </summary>
		public TaskQueue()
		{
			queue = new Queue<TaskExecution>();
			tasksAvailable = new ManualResetEvent(false);
		}
		/// <summary>
		/// Примитив, на котором можно ждать поступления задач.
		/// </summary>
		public WaitHandle HasTasksAvailable
		{
			get { return tasksAvailable; }
		}
		/// <summary>
		/// Поставить набор задач в очередь на выполнение. Ахтунг: NOT FUCKING THREAD SAFE. 
		/// Для синхронизации используйте сам экземпляр TaskQueue.
		/// </summary>
		public void Enqueue(TaskExecution item)
		{
			queue.Enqueue(item);
			tasksAvailable.Set();
		}
		/// <summary>
		/// Взять задачу из очереди на выполнение. Thread-safe.
		/// </summary>
		/// <returns>Задачу из очереди или null, если нет.</returns>
		public TaskExecution Dequeue()
		{
			lock (this)
			{
				int tasksLeft = queue.Count;
				if (tasksLeft == 0)
					return null;
				if (tasksLeft == 1)
					tasksAvailable.Reset();
				return queue.Dequeue();
			}
		}
	}
}
